#include "CImageDecoderProcess.h"
#include "global.h"

CImageDecoderProcess::CImageDecoderProcess() : CActive(EPriorityLow)
{
	CActiveScheduler::Add(this);
}

CImageDecoderProcess::~CImageDecoderProcess()
{
	if(iDecoder)
		{
		iDecoder->Cancel();
		delete iDecoder;
		}
		
}

CImageDecoderProcess* CImageDecoderProcess::NewL(MImageLoadedNotify* aImageLoadedNotify)
{
	CImageDecoderProcess* self = new(ELeave) CImageDecoderProcess;
	CleanupStack::PushL(self);
	self->ConstructL(aImageLoadedNotify);
	CleanupStack::Pop(self);
	
	return self;
}

void CImageDecoderProcess::ConstructL(MImageLoadedNotify* aImageLoadedNotify)
{
	iImageLoadedNotify = aImageLoadedNotify;

	iDecoder = CImageDecoder::FileNewL( UIControlEnv::Static()->FsSession(), aImageLoadedNotify->GetFileName(),
		 CImageDecoder::TOptions(	CImageDecoder::EAllowGeneratedMask | CImageDecoder::EOptionNoDither));
	
	if(!iDecoder) 
		return;
	
	RArray<TFrame>* iFrameArray = aImageLoadedNotify->GetFrames();
	if(!iFrameArray)
		return;
	
	TInt cnt = iDecoder->FrameCount();
	if(cnt==0)
		User::Leave(KErrCorrupt);
	
	for(TInt i=0;i<cnt;i++)
	{
		TFrame frame;
		
		TFrameInfo frameInfo = iDecoder->FrameInfo(i);
		frame.iPosition = frameInfo.iFrameCoordsInPixels.iTl;
		frame.iBackColor = frameInfo.iBackgroundColor;
		frame.iSize = frameInfo.iOverallSizeInPixels;
//		if(i==0)
//			iImage->iSize = frameInfo.iOverallSizeInPixels;
		frame.iFlags = frameInfo.iFlags;
		frame.iDelay = frameInfo.iDelay;
		if(frame.iDelay.Int64()==0)
			frame.iDelay = 100*1000;
		iFrameArray->Append(frame);
	}
	
	ConvertL();
}

void CImageDecoderProcess::ConvertL()
{
	if(!iImageLoadedNotify)
		return;
	RArray<TFrame>* iFrameArray = iImageLoadedNotify->GetFrames();
	if(!iFrameArray)
		return;
	
	TFrame& frame = (*iFrameArray)[iResolvingFrame];
	frame.iBitmap = new (ELeave) CFbsBitmap();
	frame.iBitmap->Create( frame.iSize, iDecoder->FrameInfo(iResolvingFrame).iFrameDisplayMode );

	if(frame.iFlags & TFrameInfo::ETransparencyPossible)
	{
		frame.iBitmapMask = new (ELeave) CFbsBitmap();
		if(frame.iFlags & TFrameInfo::EAlphaChannel)
			frame.iBitmapMask->Create(frame.iSize, EGray256);
		else
			frame.iBitmapMask->Create(frame.iSize, EGray2);
	}
	
	if(frame.iBitmapMask)
		iDecoder->Convert( &iStatus, *frame.iBitmap, *frame.iBitmapMask,  iResolvingFrame);
	else
		iDecoder->Convert( &iStatus, *frame.iBitmap , iResolvingFrame);
	
	SetActive();
}

void CImageDecoderProcess::RunL()
{
	if(!iImageLoadedNotify)
		return;
	RArray<TFrame>* iFrameArray = iImageLoadedNotify->GetFrames();
	if(!iFrameArray)
		return;
	
	if(iStatus!=KErrNone) 
	{
		delete this;
	}
	else 
	{
		(*iFrameArray)[iResolvingFrame].iConverted = ETrue;
		iResolvingFrame++;
		if(iResolvingFrame<iFrameArray->Count()) 
			ConvertL();
		else
			{
			iImageLoadedNotify->LoadedCompleteNotify();
			delete this;
			}
	}
}

void CImageDecoderProcess::DoCancel()
{
	if(iDecoder) 
		iDecoder->Cancel();
}

TInt CImageDecoderProcess::RunError(TInt /*aError*/)
{
	delete this;
	return KErrNone;
}